using System;
using System.Collections.Generic;
using System.Text;

namespace EuropeEngulfed.NET
{
    class SeaRegionState : RegionState
    {
        private List<FleetPoint> fleets;
        public SeaRegionState(MapInfo.RegionID regionID)
        {
            this.regionID = regionID;
            fleets = new List<FleetPoint>();
        }

        public void AddFleetPoint(FleetPoint fleetPointToAdd)
        {
            foreach (FleetPoint fleet in fleets)
            {
                if (fleetPointToAdd == fleet)
                    return;
            }
            fleets.Add(fleetPointToAdd);
        }

        public void RemoveFleetPoint(FleetPoint fleetPointToRemove)
        {
            fleets.Remove(fleetPointToRemove);
        }

        public FleetPoint GetFleetPointAt(int iIndex)
        {
            if (iIndex < fleets.Count)
                return fleets[iIndex];
            else
                return null;
        }

        public void FlipAllFleetsToTransportsAvailable()
        {
            foreach (FleetPoint fleet in fleets)
            {
                fleet.WithoutTransport = false;
            }
        }

        public void FlipCountryFleetsToWithoutTransports(int numFleetsToFlip, MapInfo.CountryID country)
        {
            for (int i = 0; i < numFleetsToFlip; i++)
            {
                foreach (FleetPoint fleet in fleets)
                {
                    if (fleet.CountryOwner == country)
                    {
                        if (!fleet.WithoutTransport)
                        {
                            fleet.WithoutTransport = true;
                            break;
                        }
                    }
                }
            }
        }

        public void FlipAlliedFleetsToWithoutTransports(int numFleetsToFlip)
        {
            for (int i = 0; i < numFleetsToFlip; i++)
            {
                foreach (FleetPoint fleet in fleets)
                {
                    if (fleet.CountryOwner == MapInfo.CountryID.France || fleet.CountryOwner == MapInfo.CountryID.GreatBritain || fleet.CountryOwner == MapInfo.CountryID.USSR || fleet.CountryOwner == MapInfo.CountryID.USA)
                    {
                        if (!fleet.WithoutTransport)
                        {
                            fleet.WithoutTransport = true;
                            break;
                        }
                    }
                }
            }
        }

        public void FlipAxisFleetsToWithoutTransports(int numFleetsToFlip)
        {
            for (int i = 0; i < numFleetsToFlip; i++)
            {
                foreach (FleetPoint fleet in fleets)
                {
                    if (fleet.CountryOwner == MapInfo.CountryID.Germany || fleet.CountryOwner == MapInfo.CountryID.Italy)
                    {
                        if(!fleet.WithoutTransport)
                        {
                            fleet.WithoutTransport = true;
                            break;
                        }
                    }
                }
            }
        }

        public void RemoveNonFrenchAlliedFleetPoints(int numFleetPointsToDestroy)
        {
            for(int i = 0; i < numFleetPointsToDestroy; i++)
            {
                foreach (FleetPoint fleet in fleets)
                {
                    if (fleet.CountryOwner == MapInfo.CountryID.GreatBritain || fleet.CountryOwner == MapInfo.CountryID.USSR || fleet.CountryOwner == MapInfo.CountryID.USA)
                    {
                        RemoveFleetPoint(fleet);
                        break;
                    }
                }
            }
        }

        public void RemoveFrenchFleetPoints(int numFleetPointsToDestroy)
        {
            for (int i = 0; i < numFleetPointsToDestroy; i++)
            {
                foreach (FleetPoint fleet in fleets)
                {
                    if (fleet.CountryOwner == MapInfo.CountryID.France)
                    {
                        RemoveFleetPoint(fleet);
                        break;
                    }
                }
            }
        }

        public void RemoveAllFleetPoints(MapInfo.CountryID country)
        {
            bool continueLoop = true;

            while(continueLoop)
            {
                continueLoop = false;
                foreach (FleetPoint fleet in fleets)
                {
                    if (fleet.CountryOwner == country)
                    {
                        RemoveFleetPoint(fleet);
                        continueLoop = true;
                        break;
                    }
                }
            }
        }

        public void RemoveAxisFleetPoints(int numFleetPointsToDestroy)
        {
            for (int i = 0; i < numFleetPointsToDestroy; i++)
            {
                foreach (FleetPoint fleet in fleets)
                {
                    if (fleet.CountryOwner == MapInfo.CountryID.Germany || fleet.CountryOwner == MapInfo.CountryID.Italy)
                    {
                        RemoveFleetPoint(fleet);
                        break;
                    }
                }
            }
        }

        public int GetNumberOfAxisFleetPoints()
        {
            int fleetpoints = 0;
            foreach(FleetPoint fleet in fleets)
            {
                if (fleet.CountryOwner == MapInfo.CountryID.Germany || fleet.CountryOwner == MapInfo.CountryID.Italy)
                    fleetpoints++;
            }
            return fleetpoints;
        }

        public int GetNumberOfAlliedFleetPoints()
        {
            int fleetpoints = 0;
            foreach (FleetPoint fleet in fleets)
            {
                if (fleet.CountryOwner == MapInfo.CountryID.France || fleet.CountryOwner == MapInfo.CountryID.GreatBritain || fleet.CountryOwner == MapInfo.CountryID.USSR)
                    fleetpoints++;
            }
            return fleetpoints;
        }

        public override void SetAllAxisPlayingPiecesAsUnSupplied(GameState gameState)
        {
            foreach (FleetPoint fleet in fleets)
            {
                if (gameState.IsAxisCountry(fleet.CountryOwner))
                    fleet.OutOfSupplyState = PlayingPiece.OOSState.OOS;
            }
        }

        public override void SetAllAlliedPlayingPiecesAsUnSupplied(GameState gameState)
        {
            foreach (FleetPoint fleet in fleets)
            {
                if (gameState.IsAlliedCountry(fleet.CountryOwner))
                    fleet.OutOfSupplyState = PlayingPiece.OOSState.OOS;
            }
        }

        public override System.Xml.XmlNode Serialise(System.Xml.XmlDocument xml)
        {
            System.Xml.XmlNode nodeToReturn = xml.CreateElement("SeaRegionState");
            System.Xml.XmlAttribute regionIDAttr = xml.CreateAttribute("RegionID");
            regionIDAttr.Value = Enum.GetName(typeof(MapInfo.RegionID), this.regionID);
            nodeToReturn.Attributes.Append(regionIDAttr);

            foreach(FleetPoint fleet in fleets)
            {
                nodeToReturn.AppendChild(fleet.Serialise(xml));
            }

            return nodeToReturn;
        }

        public static new RegionState Deserialise(System.Xml.XmlNode node)
        {
            SeaRegionState seaRegionStateToReturn = null;

            if(node.Name == "SeaRegionState")
            {
                seaRegionStateToReturn = new SeaRegionState((MapInfo.RegionID)Enum.Parse(typeof(MapInfo.RegionID), node.Attributes["RegionID"].Value));
                foreach (System.Xml.XmlNode seaRegionStateNode in node)
                {
                    switch (seaRegionStateNode.Name)
                    {
                        case "FleetPoint":
                            seaRegionStateToReturn.fleets.Add(FleetPoint.Deserialise(seaRegionStateNode));
                            break;
                    }
                }
            }

            return seaRegionStateToReturn;
        }

        public override bool Equals(RegionState regionStateToCompare)
        {
            if (regionStateToCompare is SeaRegionState)
            {
                SeaRegionState seaRegionStateToCompare = (SeaRegionState)regionStateToCompare;
                if (this.regionID != seaRegionStateToCompare.regionID)
                    return false;
                if (this.fleets.Count != seaRegionStateToCompare.fleets.Count)
                    return false;
                List<FleetPoint> listOfFleetsToCompare = new List<FleetPoint>(seaRegionStateToCompare.fleets);
                foreach (FleetPoint fleet in this.fleets)
                {
                    bool found = false;
                    foreach (FleetPoint fleetToLookFor in listOfFleetsToCompare)
                    {
                        if (fleet.Equals(fleetToLookFor))
                        {
                            found = true;
                            listOfFleetsToCompare.Remove(fleetToLookFor);
                            break;
                        }
                    }
                    if (!found)
                        return false;
                }
                return true;
            }
            else
                return false;
        }
    }
}
